#ifndef LIBRARY_RENTRY_H
#define LIBRARY_RENTRY_H

namespace Library
{

/**
 * A concrete class which provides read-only management of in-memory and
 * on-disk resources (via ResourceFile).
 */
class ResourceEntry
{
	public:
						ResourceEntry();
		virtual			~ResourceEntry();

		// ResourceEntry originals
		virtual	void *	acquire();
		virtual	bool8	load(pStream is, uint8 format);
		virtual	String	name();
		virtual	bool8	release();
		virtual	uint32	size();
		virtual	uint32	timestamp();
		virtual	uint32	useCount();
		virtual	void *	userData();
		virtual	void	userData(void * data);

	protected:
		virtual	bool8	loadData();

	protected:
		String			m_name;
		uint32			m_size;
		void *			m_data;
		uint32			m_usecount;
		void *			m_userdata;
		uint32			m_timestamp;

		uint32			m_isizecompressed;
		pStream			m_istream;
		uint32			m_ioffset;

	// namespace
	protected:
		struct DiskImage_versionD;
		struct DiskImage_versionC;
		struct DiskImage_versionA;

	// prohibited
	private:
		ResourceEntry(ResourceEntry &);
		ResourceEntry & operator=(ResourceEntry &);
};

/**
 * REVISIT: Comment this structure.
 */
#define RE_DISKIMAGEFORMAT_VERSION_D		'D'
#define RE_CURRENT_DISKIMAGEFORMAT			RE_DISKIMAGEFORMAT_VERSION_D
struct ResourceEntry::DiskImage_versionD
{
	uint32		m_offset;
	uint32		m_size;
	uint32		m_sizecompressed;
	uint32		m_timestamp;
	uint32		m_namelength;
	// The name of the resource immediately follows (note: non-terminated).
};

/**
 * Deprecated.  This is the compressed version of DiskImage_versionA.  It
 * was created for the release of 16-bit graphics (Release 1.3.0), and used
 * in 2004.
 */
#define RE_DISKIMAGEFORMAT_VERSION_C		'C'
struct ResourceEntry::DiskImage_versionC
{
	char 		m_name[ 16 ];
	uint32		m_offset;
	uint32		m_size;
	uint32		m_sizecompressed;
};

//
// NOTE: ResourceEntry::DiskImage_versionB never existed.  It just so happens
//       we have a hole in our version scheme.
//

/**
 * Deprecated.  This is the original version developed back in the days of
 * Pixel Technologies and used from 1996-2004.
 */
#define RE_DISKIMAGEFORMAT_VERSION_A		0
struct ResourceEntry::DiskImage_versionA
{
	char 		m_name[ 16 ];
	uint32		m_offset;
	uint32		m_size;
};


//----------------------------------------------------------------------------
// Inline
//

/**
 * @return		A pointer to a null-terminated string containing the name
 *				of the resource.
 */
inline String
ResourceEntry::name()
{
	return m_name;
}

/**
 * @return		The size of the resource, in bytes.
 */
inline uint32
ResourceEntry::size()
{
	return m_size;
}

/**
 * @return		The time of last modification for the resource.
 */
inline uint32
ResourceEntry::timestamp()
{
	return m_timestamp;
}

/**
 * @return		The number of outstanding resource references.
 */
inline uint32
ResourceEntry::useCount()
{
	return m_usecount;
}

/**
 * @return		A void pointer to user specified data.
 */
inline void *
ResourceEntry::userData()
{
	return m_userdata;
}

/**
 * @param data	A void pointer a any piece of data which should be associated
 *				with the resource and shared with other users of the resource.
 *
 * <b>Developer Notes:</b>
 *
 * Care should be taken when storing user data with the resource, since
 * destruction of a resource, and its entry, does not deallocate/destruct/etc
 * the user data.  Therefore, it is the calling class' responsibility to call
 * getUseCount() and getUserData() during its destruction and
 * deallocate/destruct/unassign/etc the user data when the use count drops to
 * zero (0).  Failure to do so will most likely result in a memory leak of the
 * user data.
 */
inline void
ResourceEntry::userData(void * data)
{
	m_userdata = data;
}

}; // namespace Library

#endif
